package com.canbot.u05.socket;

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.v4.content.LocalBroadcastManager;

import com.alibaba.fastjson.JSON;
import com.canbot.u05.activity.presidemode.HostModeListViewActivity;
import com.canbot.u05.utils.ConstUtils;
import com.canbot.u05.utils.Logger;
import com.canbot.u05.utils.ToastTools;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * socket通信管理
 */
public class HeadSocketManager {

        private static final String TAG = "HeadSocketManager";

        private static final boolean isDebug = false;

        private static HeadSocketManager instance;

        private Context mContext;

        private volatile Socket mSocket;

        private volatile DataOutputStream mDataOutputStream;

        private ToastTools toastTools;

        private HandlerThread handlerThread;

        private Handler mHandler2;

        private ThreadPoolProxy threadPoolProxy;

        private volatile DataInputStream mInputStream;

        private Runnable mRunnable;

        private HeadSocketManager() {

        }

        public static HeadSocketManager getInstance() {
                if (instance == null) {
                        instance = new HeadSocketManager();
                }
                return instance;
        }

        /**
         * 初始化
         *
         * @author liuyusheng
         */
        public void init(Context context, final Runnable runnable) {
                Logger.e(TAG, "init  ");
                this.mContext = context;
                this.mRunnable = runnable;
                toastTools = ToastTools.newInstance(mContext);
                handlerThread = new HandlerThread(TAG);
                handlerThread.start();
                mHandler2 = new Handler(handlerThread.getLooper()) {
                        @Override
                        public void handleMessage(Message msg) {
                                switch (msg.what) {
                                        case 0:
                                                sendStringMsgToServer(JSON.toJSONString(new StringMsgBean(MsgType.HEARTBEAT, "heartbeat")));
                                                sendEmptyMessageDelayed(0, 2000);
                                                break;
                                        case 1:
                                                removeMessages(0);
                                                connectToServer();
                                                break;
                                        default:
                                                break;
                                }

                        }
                };
                threadPoolProxy = new ThreadPoolProxy(3, 5);
                mHandler2.sendEmptyMessage(1);
        }

        /**
         * 通过wifi热点通信时 的IP和Port
         */
        public static final int SOCKET_PORT = 19255;

        private void connectToServer() {
                releaseLastSocket();
                try {
                        Logger.e(TAG, "try connect to " + IpMsgConst.HEAD_SOCKET_HOST);
                        mSocket = new Socket();
                        mSocket.connect(new InetSocketAddress(IpMsgConst.HEAD_SOCKET_HOST, SOCKET_PORT));
                        Logger.e(TAG, "连接成功  " + IpMsgConst.HEAD_SOCKET_HOST);
                        mDataOutputStream = new DataOutputStream(mSocket.getOutputStream());
                        mInputStream = new DataInputStream(mSocket.getInputStream());
                        mHandler2.sendEmptyMessage(0);
                        if (mRunnable != null) {
                                mRunnable.run();
                                mRunnable = null;
                        }
                        handleSocket();
                }
                catch (UnknownHostException e) {
                        Logger.e(TAG, "连接失败  " + IpMsgConst.CHEST_SOCKET_HOST);
                        e.printStackTrace();
                        mHandler2.sendEmptyMessageDelayed(1, 2 * 1000);
                }
                catch (IOException e) {
                        e.printStackTrace();
                        mHandler2.sendEmptyMessageDelayed(1, 2 * 1000);
                }
                catch (RuntimeException e) {
                        Logger.e(TAG, "RuntimeException:" + e.getLocalizedMessage());
                        e.printStackTrace();
                }
        }

        private void handleSocket() {
                if (threadPoolProxy == null) {
                        return;
                }
                threadPoolProxy.execute(new Runnable() {
                        @Override
                        public void run() {
                                try {
                                        Logger.d(TAG, "SocketThread running!");
                                        while (true) {
                                                synchronized (HeadSocketManager.this) {
                                                        if (mInputStream == null) {
                                                                return;
                                                        }
                                                }
                                                Logger.d(TAG, "befor read---------!");
                                                final String resultStr = mInputStream.readUTF();
                                                handleStringMsg(resultStr);
                                        }
                                }
                                catch (IOException e) {
                                        e.printStackTrace();
                                        mHandler2.sendEmptyMessageDelayed(1, 2 * 1000);
                                }
                        }
                });
        }

        public void destroy() {
                releaseLastSocket();
                mHandler2.removeCallbacksAndMessages(null);
                handlerThread.quitSafely();
                if (threadPoolProxy != null) {
                        threadPoolProxy.shutDown();
                        threadPoolProxy = null;
                }

        }

        /**
         * 断开连接
         */
        private synchronized void releaseLastSocket() {
                if (mInputStream != null) {
                        try {
                                mInputStream.close();
                        }
                        catch (IOException e) {
                                e.printStackTrace();
                        }
                }
                if (mDataOutputStream != null) {
                        try {
                                mDataOutputStream.close();
                        }
                        catch (IOException e) {
                                e.printStackTrace();
                        }
                }
                if (null != mSocket) {
                        if (!mSocket.isClosed()) {
                                try {
                                        mSocket.close();
                                }
                                catch (IOException e) {
                                        e.printStackTrace();
                                }
                        }
                }

                mInputStream = null;
                mDataOutputStream = null;
                mSocket = null;
        }


        /**
         * 处理String 消息
         *
         * @param data
         */
        private void handleStringMsg(String data) {
                if (data != null) {
                        StringMsgBean strMsgBean = JSON.parseObject(data, StringMsgBean.class);
                        if (strMsgBean != null) {

                                int msgType = strMsgBean.getMsgType();
                                String msgData = strMsgBean.getMsgData();
                                Logger.d(TAG, "StringMsgBean===" + strMsgBean.toString() + ",msgType=  " + msgType);
                                switch (msgType) {
                                        case MsgType.HEARTBEAT:
                                                if (isDebug) {
                                                        toastTools.showText("收到头部心跳");
                                                }
                                                break;

                                        // 默认都是无参数直接传递.
                                        default:
                                                break;

                                }
                        }
                        else {
                                Logger.d(TAG, "stringMsgBean parse is null！");
                        }
                }
        }

        /**
         * 发送信息失败时先将信息缓存起来等socket连接成功之后再发送出去。
         *
         * @param msg
         * @return
         */
        public boolean sendStringMsgToServer(final String msg) {
                if (threadPoolProxy == null) {
                        return false;
                }
                threadPoolProxy.execute(new Runnable() {
                        @Override
                        public void run() {
                                synchronized (HeadSocketManager.this) {
                                        Logger.e(TAG, "sendStringMsgToServer  start msg: " + msg);
                                        if (mDataOutputStream != null) {
                                                Logger.e(TAG, "mDataOutputStream != null");
                                                try {
                                                        mDataOutputStream.writeUTF(msg);
                                                        mDataOutputStream.flush();
                                                        Logger.e(TAG, "sendStringMsgToServer  success");
                                                }
                                                catch (IOException e) {
                                                        Logger.e(TAG, "sendStringMsgToServer  fail");
                                                        e.printStackTrace();
                                                        mHandler2.sendEmptyMessageDelayed(1, 2 * 1000);
                                                }
                                        }
                                }
                        }
                });
                return true;
        }

}
